# coding=utf-8
# Mako-Module einbinden
from mako.template import Template
from mako.lookup import TemplateLookup
from mako.runtime import Context
# spezielles IO-Modul, um IO in/aus Strings auszufuehren
from StringIO import StringIO

from DataHandler import *
from Helper import *
import datetime

import os.path
import cherrypy #webserver lib

#Init datahandler
DataHandlerLehrVeranstaltungObject = DataHandlerLehrVeranstaltung("data/Lehrveranstaltungen.p")
DataHandlerThemen = DataHandlerThemen("data/Themen.p")
DataHandlerMarken = DataHandlerDescriptionBase("data/Marken.p")
DataHandlerLernEinheitObject = DataHandlerLernEinheit(DataHandlerLehrVeranstaltungObject,DataHandlerThemen,"data/Lerneinheiten.p")

 # angeben, wo mako die Vorlagen findet, hier fix codiert
Lookup_o = TemplateLookup(directories=["."])

#--------------------------------------------------------------------
#Bildet eine Page zur Verwaltung und Anzeige aller DatenKlassen die DescriptionBase als BasisKlasse haben
#--------------------------------------------------------------------
class DescriptionBasePage(Page):
#--------------------------------------------------------------------
    def __init__(self,title,htmlFile,dataHandler,open):
        self.open = open
        self.title = title
        self.htmlFile = htmlFile
        self.dataHandler = dataHandler
#--------------------------------------------------------------------
    def index(self):
        #return Template("LehrVeranstaltung ${data}!").render(data="test") #return contents 
       
        # Template-Engine instanziieren, dabei Dateiname der Vorlage
        # angeben (hier fix codiert)
        # sowie Hinweis auf Ablageort weiterer (optionaler) Module
        Template_o = Template(filename=self.htmlFile,module_directory='.',lookup=Lookup_o)
        # Pufferbereich fuer IO erzeugen
        Buffer_o = StringIO()
        # Ausfuehrungskontext erzeugen, dabei den IO-Puffer zuordnen
        Context_o = Context(Buffer_o, list= self.dataHandler.ItemList,Title = self.title)
        # Vorlage mit dem aktuellen Kontext auswerten
        Template_o.render_context(Context_o)
        # Inhalt des IO-Puffers als String zurueckgeben
        return self.header() + Buffer_o.getvalue() + self.footer() 
    index.exposed = True
#--------------------------------------------------------------------
    def save(self, Bezeichner=None,Beschreibung=None):#http://localhost:8080/Lehrveranstaltungen/save/<fach>
        if Bezeichner != None:
            Bezeichner = Bezeichner.strip()
        if Beschreibung != None:
            Beschreibung = Beschreibung.strip()

        if isStrEmpty(Bezeichner) or isStrEmpty(Beschreibung):
            return  message("Beschreibung und Fach angeben!")
                
        Veranstaltung = DescriptionBase(Bezeichner,Beschreibung)

        if self.dataHandler.Add(Veranstaltung) == True:
            return  self.index()
        else:
            return  message("Fehlgeschlagen ")
    save.exposed = True
#--------------------------------------------------------------------
    def Remove(self, Bezeichner=None):#http://localhost:8080/Lehrveranstaltungen/Remove/<fach>
       
        if Bezeichner != None:
            Bezeichner = Bezeichner.strip()

        if isStrEmpty(Bezeichner):
            return  message("Bezeichner Angeben ")
        else:
            if self.dataHandler.Remove(Bezeichner) == True:
                return  self.index()
            else:
                return  message("Fehlgeschlagen ")
    Remove.exposed = True

#--------------------------------------------------------------------
#Page zur Anezige von Abschnitten
#--------------------------------------------------------------------
class AbschnittPage(Page):
#--------------------------------------------------------------------
    def index(self):
        return "nichts"
    index.exposed = True
#--------------------------------------------------------------------
    def open(self,LerneinheitNummer = None, AbschnittBezeichner = None):
        
        LerneinheitNummer = int(LerneinheitNummer)
        currentAbschnitt = None
        currentThemaBezeichner = None
        themenList = DataHandlerThemen.ItemList

        for themaObject in themenList:
            for keyValuePair in themaObject.Abschnitte:
                if keyValuePair.AbschnittBezeichner == AbschnittBezeichner and keyValuePair.LerneinheitNummer == LerneinheitNummer:
                    currentThemaBezeichner = themaObject.Bezeichner

        lerneinheitobject =   DataHandlerLernEinheitObject.GetElement(LerneinheitNummer)
        for abschnitt in lerneinheitobject.AbschnittList:
            if abschnitt.Bezeichner == AbschnittBezeichner:
                currentAbschnitt = abschnitt
                break
                
        Template_o = Template(filename="resources/Abschnitt.html",module_directory='.',lookup=Lookup_o)
        Buffer_o = StringIO()
        Context_o = Context(Buffer_o, abschnitt = currentAbschnitt,LerneinheitNummer = LerneinheitNummer,themenList = themenList,currentThemaBezeichner=currentThemaBezeichner)
        Template_o.render_context(Context_o)
        return self.header() + Buffer_o.getvalue() + self.footer() 

    open.exposed = True
    
#--------------------------------------------------------------------
#Page zur Anezige von Abschnitten
#--------------------------------------------------------------------
class LerneinheitPage(Page):
#--------------------------------------------------------------------
    def __init__(self):
        self.Abschnitt = AbschnittPage()
#--------------------------------------------------------------------
    def index(self,LerneinheitNummer=None):

        lerneinheit = None
        lernveranstaltungslist = DataHandlerLehrVeranstaltungObject.ItemList
        
        selectedLehrVeranstaltungBezeichner = None

        if LerneinheitNummer != None:
            LerneinheitNummer = LerneinheitNummer.strip()
        
            LerneinheitNummer = int(LerneinheitNummer)
            lerneinheit = DataHandlerLernEinheitObject.GetElement(LerneinheitNummer)

            for lernveranstaltungsObject in lernveranstaltungslist:
                if selectedLehrVeranstaltungBezeichner == None:
                    for einheitBeschreibung in lernveranstaltungsObject.LerneinheitListe:
                        if einheitBeschreibung == LerneinheitNummer:
                            selectedLehrVeranstaltungBezeichner = lernveranstaltungsObject.Bezeichner
                            break

            if lerneinheit == None:
                return  message("Fach existiert nicht")
        Template_o = Template(filename="resources/LerneinheitOpen.html",module_directory='.',lookup=Lookup_o)
        Buffer_o = StringIO()
        Context_o = Context(Buffer_o, Lerneinheiten = lerneinheit ,lernveranstaltungslist = DataHandlerLehrVeranstaltungObject.ItemList,markenList = DataHandlerMarken.ItemList,selectedLehrVeranstaltungBezeichner=selectedLehrVeranstaltungBezeichner)
        Template_o.render_context(Context_o)
        return self.header() + Buffer_o.getvalue() + self.footer() 

    index.exposed = True
#--------------------------------------------------------------------
    def save(self,LerneinheitNummer,Bezeichner,Beschreibung,Thema):

        if LerneinheitNummer != None:
            LerneinheitNummer = LerneinheitNummer.strip()
        if Bezeichner != None:
            Bezeichner = Bezeichner.strip()
        if Beschreibung != None:
            Beschreibung = Beschreibung.strip()
        if Thema != None:
            Thema = Thema.strip()

        if isStrEmpty(Bezeichner) or isStrEmpty(Beschreibung) or isStrEmpty(Thema) or isStrEmpty(LerneinheitNummer):
            return  message("Beschreibung und Fach angeben!")
       
        intLerneinheitNummer = int(LerneinheitNummer)

        abschnittObject = Abschnitt(Bezeichner,Beschreibung)
       
        if DataHandlerLernEinheitObject.AddAbschnitt(intLerneinheitNummer,abschnittObject,Thema) == True:
            return self.index(LerneinheitNummer)  
        else:
            return  message("Fehlgeschlagen ")
    save.exposed = True
#--------------------------------------------------------------------
    def remove(self,LerneinheitNummer,AbschnittBezeichner):

        if LerneinheitNummer != None:
            LerneinheitNummer = LerneinheitNummer.strip()
        if AbschnittBezeichner != None:
            Bezeichner = AbschnittBezeichner.strip()
     
        if isStrEmpty(Bezeichner) or isStrEmpty(LerneinheitNummer):
            return  message("Bezeichner und LerneinheitNummer angeben!")
       
        intLerneinheitNummer = int(LerneinheitNummer)
       
        if DataHandlerLernEinheitObject.RemoveAbschnitt(intLerneinheitNummer,AbschnittBezeichner) == True:
            return  self.index(LerneinheitNummer)
        else:
            return  message("Fehlgeschlagen ")
    remove.exposed = True
#--------------------------------------------------------------------
    def addMarke(self,LerneinheitNummer,Bezeichner):

        intLerneinheitNummer = int(LerneinheitNummer)
       
        if  DataHandlerLernEinheitObject.AddMarke(intLerneinheitNummer,Bezeichner) == True:
            return  self.index(LerneinheitNummer)
        else:
            return  message("Fehlgeschlagen ")
    addMarke.exposed = True
#--------------------------------------------------------------------
    def removeMarke(self,LerneinheitNummer,Bezeichner):

        intLerneinheitNummer = int(LerneinheitNummer)
       
        if  DataHandlerLernEinheitObject.RemoveMarke(intLerneinheitNummer,Bezeichner) == True:
            return  self.index(LerneinheitNummer)
        else:
            return  message("Fehlgeschlagen ")
    removeMarke.exposed = True

#--------------------------------------------------------------------
#
#--------------------------------------------------------------------
class LerneinheitenPage(Page):
#--------------------------------------------------------------------
    def __init__(self):
          self.open = LerneinheitPage()
#--------------------------------------------------------------------
    def index(self,order=None,reverse=None,orderbythema=None):
        
        LernEinheitsliste = DataHandlerLernEinheitObject.LernEinheitsList

        themenlist = DataHandlerThemen.ItemList

        if(order != None and order == 'chrono'):
            if(reverse != None and reverse == 'True'):
                LernEinheitsliste.sort(key=lambda x: x.Termin, reverse=True)
            if(reverse != None and reverse == 'False'):
                LernEinheitsliste.sort(key=lambda x: x.Termin, reverse=False)

        if(orderbythema != None):
            
            LernEinheitsliste = []

            for thema in themenlist:
                if thema.Bezeichner == orderbythema:
                    if len(thema.Abschnitte) != 0:#item enthalten
                        for keypair in thema.Abschnitte:

                            itemAdded= False
                            for lerneinheitItem in LernEinheitsliste:
                                if lerneinheitItem.Nummer == keypair.LerneinheitNummer:
                                    itemAdded = True
                                    break

                            if itemAdded == False:
                                lernObject = DataHandlerLernEinheitObject.GetElement(keypair.LerneinheitNummer)
                                LernEinheitsliste.append(lernObject)
                    break
          
        Template_o = Template(filename="resources/Lerneinheit.html",module_directory='.',lookup=Lookup_o)
        Buffer_o = StringIO()
        Context_o = Context(Buffer_o, list = LernEinheitsliste,themenlist=themenlist,selectedThema=orderbythema)
        Template_o.render_context(Context_o)
        return self.header() + Buffer_o.getvalue() + self.footer() 
    index.exposed = True
#--------------------------------------------------------------------
    def save(self, Bezeichner=None,LVBezeichner=None,Nummer=None):
        if Bezeichner != None:
            Bezeichner = Bezeichner.strip()

        if isStrEmpty(Bezeichner) :
            return  message("Beschreibung und Fach angeben!")

       
        Termin = datetime.datetime.now()    
        if Nummer == None:
            Nummer = 0
        else:
            Nummer = int(Nummer)

        LerneinheitObject = Lerneinheit(Termin,Bezeichner)
        LerneinheitObject.Nummer = Nummer

        if DataHandlerLernEinheitObject.Add(LerneinheitObject,LVBezeichner) == True:
            return self.index()  
        else:
            return  message("Fehlgeschlagen ")
    save.exposed = True
#--------------------------------------------------------------------
    def Remove(self, LerneinheitNummer=None):
       
        if LerneinheitNummer != None:
            LerneinheitNummer = int(LerneinheitNummer.strip())

        if DataHandlerLernEinheitObject.Remove(LerneinheitNummer) == True:
            return  self.index()
        else:
            return  message("Fehlgeschlagen ")
    Remove.exposed = True
#--------------------------------------------------------------------
#
#--------------------------------------------------------------------
class Lehrveranstaltung(Page):#http://localhost:8080/Lehrveranstaltungen/open/<fach>
#--------------------------------------------------------------------
    def index(self, Bezeichner=None):
        lerneinheitlist = []
        lehrVeranstaltung = None
        if Bezeichner != None:
            Bezeichner = Bezeichner.strip()

            lehrVeranstaltung = DataHandlerLehrVeranstaltungObject.GetElement(Bezeichner)
            if lehrVeranstaltung == None:
                return  message("Fach existiert nicht")
          
            for LernEinheitNummer in lehrVeranstaltung.LerneinheitListe:
                lerneinheit = DataHandlerLernEinheitObject.GetElement(LernEinheitNummer)
                if lerneinheit != None:
                    lerneinheitlist.append(lerneinheit)
           
        Template_o = Template(filename="resources/LehrVeranstaltungOpen.html",module_directory='.',lookup=Lookup_o)
        Buffer_o = StringIO()


        Context_o = Context(Buffer_o, LehrVeranstaltung = lehrVeranstaltung,lerneinheitlist = lerneinheitlist)

        Template_o.render_context(Context_o)
        return self.header() + Buffer_o.getvalue() + self.footer() 
    index.exposed = True
#--------------------------------------------------------------------
#
#--------------------------------------------------------------------
class LehrveranstaltungenPage(DescriptionBasePage):
#--------------------------------------------------------------------
    def save(self, Bezeichner=None,Beschreibung=None):
        if Bezeichner != None:
            Bezeichner = Bezeichner.strip()
        if Beschreibung != None:
            Beschreibung = Beschreibung.strip()

        if isStrEmpty(Bezeichner) or isStrEmpty(Beschreibung):
            return  message("Beschreibung und Fach angeben!")
                
        Veranstaltung = LehrVeranstaltung(Bezeichner,Beschreibung)

        if self.dataHandler.Add(Veranstaltung) == True:
            return  self.index()
        else:
            return  message("Fehlgeschlagen ")
    save.exposed = True
#--------------------------------------------------------------------
#
#--------------------------------------------------------------------
class ThemenPage(DescriptionBasePage):
#--------------------------------------------------------------------
    def save(self, Bezeichner=None,Beschreibung=None):
        if Bezeichner != None:
            Bezeichner = Bezeichner.strip()
        if Beschreibung != None:
            Beschreibung = Beschreibung.strip()

        if isStrEmpty(Bezeichner) or isStrEmpty(Beschreibung):
            return  message("Beschreibung und Fach angeben!")
                
        Veranstaltung = Thema(Bezeichner,Beschreibung)

        if self.dataHandler.Add(Veranstaltung) == True:
            return  self.index()
        else:
            return  message("Fehlgeschlagen")
    save.exposed = True
#--------------------------------------------------------------------
#
#--------------------------------------------------------------------
class ThemaPage(Page):
#--------------------------------------------------------------------
    def index(self, Bezeichner=None):
        
        themenObject = None

        if Bezeichner != None:
            Bezeichner = Bezeichner.strip()

            themenObject = DataHandlerThemen.GetElement(Bezeichner)
            if themenObject == None:
                return  message("Fach existiert nicht")
       
           
        Template_o = Template(filename="resources/SingleThema.html",module_directory='.',lookup=Lookup_o)
        Buffer_o = StringIO()

        Context_o = Context(Buffer_o, thema = themenObject)

        Template_o.render_context(Context_o)
        return self.header() + Buffer_o.getvalue() + self.footer() 

    index.exposed = True
#--------------------------------------------------------------------
#
#--------------------------------------------------------------------
class MarkePage(Page):
#--------------------------------------------------------------------
    def index(self,Bezeichner=None):
      
        markeObject = None
        LernEinheitslisteDisplay = []
        if Bezeichner != None:
            markeObject = DataHandlerMarken.GetElement(Bezeichner)
       
            LernEinheitsliste = DataHandlerLernEinheitObject.LernEinheitsList
            for lerneinheitObject in LernEinheitsliste:
                if lerneinheitObject.MarkenList != None:
                    for markenBezeichner in lerneinheitObject.MarkenList:
                        if markenBezeichner == Bezeichner:
                            LernEinheitslisteDisplay.append(lerneinheitObject)
                            break
        
        Template_o = Template(filename="resources/MarkeOpen.html",module_directory='.',lookup=Lookup_o)
        Buffer_o = StringIO()

        Context_o = Context(Buffer_o, marke = markeObject,lerneinheitList = LernEinheitslisteDisplay)

        Template_o.render_context(Context_o)
        return self.header() + Buffer_o.getvalue() + self.footer() 

    index.exposed = True

#--------------------------------------------------------------------
#
#--------------------------------------------------------------------
class FragenPage(Page):
#--------------------------------------------------------------------
    def index(self,orderbythema=None):

        beantworteteFragenList = []
        unBeantworteteFragenList = []

        einheitListObject = DataHandlerLernEinheitObject.LernEinheitsList

        themenList = DataHandlerThemen.ItemList

        if orderbythema != None:
            for thema in themenList:
                if thema.Bezeichner == orderbythema:
                    if len(thema.Abschnitte) != 0:#item enthalten
                        for keypair in thema.Abschnitte:

                            for einheitObject in einheitListObject:
                                if einheitObject.Nummer == keypair.LerneinheitNummer:
                                    for abschnittObject in einheitObject.AbschnittList:
                                        if abschnittObject.Bezeichner == keypair.AbschnittBezeichner:
                                            for frageObject in abschnittObject.Fragen:
                                                if frageObject.Antwort != None:
                                                    beantworteteFragenList.append(FragenContainer(einheitObject.Nummer,abschnittObject.Bezeichner,frageObject))
                                                else:
                                                    unBeantworteteFragenList.append(FragenContainer(einheitObject.Nummer,abschnittObject.Bezeichner,frageObject))

        else:
            for einheitObject in einheitListObject:
                for abschnittObject in einheitObject.AbschnittList:
                    for frageObject in abschnittObject.Fragen:
                        if frageObject.Antwort != None:
                            beantworteteFragenList.append(FragenContainer(einheitObject.Nummer,abschnittObject.Bezeichner,frageObject))
                        else:
                            unBeantworteteFragenList.append(FragenContainer(einheitObject.Nummer,abschnittObject.Bezeichner,frageObject))
         


        Template_o = Template(filename="resources/Fragen.html",module_directory='.',lookup=Lookup_o)
        Buffer_o = StringIO()

        Context_o = Context(Buffer_o, beantworteteFragenList= beantworteteFragenList,unBeantworteteFragenList=unBeantworteteFragenList,themenlist=themenList,selectedThema=orderbythema)

        Template_o.render_context(Context_o)
        return self.header() + Buffer_o.getvalue() + self.footer() 

    index.exposed = True
#--------------------------------------------------------------------
    def save(self,FrageText=None,AntwortText=None,LerneinheitNummer = None, AbschnittBezeichner = None):
        if isStrEmpty(LerneinheitNummer) or isStrEmpty(AbschnittBezeichner):
             return message("Fach und Abschnitt Angeben")

        LerneinheitNummer = int(LerneinheitNummer)

        frage = DataHandlerLernEinheitObject.GetFrageObject(LerneinheitNummer,AbschnittBezeichner,FrageText)
        if frage != None:#frage schon vorhanden löschen und neues hinzufügen mit evtl änderungen
            DataHandlerLernEinheitObject.RemoveFrageToAbschnitt(LerneinheitNummer,AbschnittBezeichner,FrageText)

        frage = Frage(FrageText)
        if not isStrEmpty(AntwortText):
            frage.SetAntwort(Antwort(AntwortText))

        
        
        if DataHandlerLernEinheitObject.AddFrageToAbschnitt(LerneinheitNummer,AbschnittBezeichner,frage) == True:
            return  self.index()
        else:
            return  message("Fehlgeschlagen ")

    save.exposed = True
#--------------------------------------------------------------------
    def remove(self,FrageText=None,LerneinheitNummer = None, AbschnittBezeichner = None):
        if isStrEmpty(LerneinheitNummer) or isStrEmpty(AbschnittBezeichner):
             return message("Fach und Abschnitt Angeben")
        LerneinheitNummer = int(LerneinheitNummer)

        if DataHandlerLernEinheitObject.RemoveFrageToAbschnitt(LerneinheitNummer,AbschnittBezeichner,FrageText) == True:
            return  self.index()
        else:
            return  message("Fehlgeschlagen ")
         
    remove.exposed = True
#--------------------------------------------------------------------
    def open(self,FrageText=None,LerneinheitNummer = None, AbschnittBezeichner = None):

        Template_o = Template(filename="resources/FrageOpen.html",module_directory='.',lookup=Lookup_o)
        Buffer_o = StringIO()

        intLerneinheitNummer = int(LerneinheitNummer)
        frageObject = None
        if FrageText != None and LerneinheitNummer != None and AbschnittBezeichner != None:
            frageObject = DataHandlerLernEinheitObject.GetFrageObject(intLerneinheitNummer,AbschnittBezeichner,FrageText)

        if frageObject != None and frageObject.Antwort != None:
            antwort = frageObject.Antwort.Text
            Context_o = Context(Buffer_o, LerneinheitNummer= intLerneinheitNummer,AbschnittBezeichner=AbschnittBezeichner,FrageText= frageObject.Text,AntwortText=antwort)
        else:
             Context_o = Context(Buffer_o, LerneinheitNummer= intLerneinheitNummer,AbschnittBezeichner=AbschnittBezeichner,FrageText= FrageText,AntwortText=None)

     
        Template_o.render_context(Context_o)
        return self.header() + Buffer_o.getvalue() + self.footer() 
    open.exposed = True
#--------------------------------------------------------------------
#
#--------------------------------------------------------------------
class Root(Page):
#--------------------------------------------------------------------
    def __init__(self):
        self.Lehrveranstaltungen = LehrveranstaltungenPage("Lehrveranstaltung","resources/DescriptionBase.html",DataHandlerLehrVeranstaltungObject,Lehrveranstaltung())##127.0.0.1:8080/LehrVeranstaltung
        self.Lerneinheiten = LerneinheitenPage()
        self.Marken = DescriptionBasePage("Marken","resources/DescriptionBase.html",DataHandlerMarken,MarkePage())
        self.Themen = ThemenPage("Themen","resources/DescriptionBase.html",DataHandlerThemen,ThemaPage())
        self.Fragen = FragenPage() 
        self.Abschnitt = AbschnittPage();
#--------------------------------------------------------------------
    def index(self): #index = root url http://localhost:8080/
        return self.header() + self.footer()
    index.exposed = True #method exposed ->accessible via the Web
#--------------------------------------------------------------------
def main():
    # Bezugspunkt verwendet werden kann   
    try:                                    # aktuelles Verzeichnis als absoluter Pfad
        currentDir_s = os.path.dirname(os.path.abspath(__file__))
    except:
        currentDir_s = os.path.dirname(os.path.abspath(sys.executable))
    cherrypy.Application.currentDir_s = currentDir_s

    tutconf = os.path.join(os.path.dirname(__file__), 'config\\default.conf')
    #cherrypy.config.update({'server.socket_host': '127.0.0.1','server.socket_port': 8080})
  
    cherrypy.config["tools.encode.on"] = True
    cherrypy.config["tools.encode.encoding"] = "utf-8"
    cherrypy.quickstart(Root(),'/', config=tutconf)		
#--------------------------------------------------------------------
if __name__ == '__main__':
    main()




